/* Copyright (c) 2011 Alexandre Défossez
 * This file is part of HINAPT.
 *
 * HINAPT is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * HINAPT is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with HINAPT.  If not, see <http://www.gnu.org/licenses/>.
 */

 /*!
  \file HeadPosition.hpp
  Implémantation du calcul de la position de la tête à partir de la position
  des deux yeux
 */

#ifndef HEADPOSITION_H
#define HEADPOSITION_H

#include "_tracker.hpp"

/*!
  Permet de déterminer la position de la tête
*/
class HeadPosition
{
  public:
    /*!
    \note Toutes les longueures seront données dans une unité arbitraire
    mais la même pour toutes les valeurs
    \param screenHeight la hauteur de l'écran
    \param eyesDistance la distance
    \param camAngle l'angle que fait la caméra avec le plan de l'écran
    autour de l'axe Ox.
    \param camWidth la largeur de la résolution de la caméra en pixel
    \param camHeight la hauteur de la résolution de la caméra en pixel
    \param camIsAbove si la caméra est au dessus ou au dessous de l'écran
    \param field le champ de la caméra (en radians)
    \param scaling les mesures seront multipliées par scaling
    */
    HeadPosition(double screenHeight,
                 double eyesDistance, double camAngle,
                 int camWidth, int camHeight, bool camIsAbove=true,
                 double field=M_PI_2, double scaling=1.
                 );
    /*!
      Calcul la position de la tête par rapport au centre de l'écran,
      avec l'axe Oz sortant de l'écran vers l'utilisateur,
      l'axe Ox vers la droite et l'axe Oy vers le haut
      \param eyes la position des deux yeux
      \param A[out] matrice de transformation dans le plan, utilisé par
      l'AffineTracker comme aide
      \return la position (x,y,z) de la tête
    */
    Point3d operator()(vector<Point2f> &eyes, Mat& A);
    /*!
      Sauvegarde les paramètres initiaux pour pouvoir déterminer A
      par la suite \see operator()(vector<Point2f> &eyes, Mat& A)
      \param eyes[in] la position actuelle des deux yeux
    */
    void setOriginalPositions(vector<Point2f> &eyes);
  private:
    /*!
      La hauteur de l'écran
    */
    double screenHeight;
    /*!
      La distance entre les deux yeux
    */
    double eyesDistance;
    /*!
      L'angle de la caméra par rapport au plan de l'écran
    */
    double camAngle;
    /*!
      Résolution de la caméra : largeur, en pixel
    */
    int camWidth;
    /*!
      Résolution de la caméra : hauteur, en pixel
    */
    int camHeight;
    /*!
      true si la caméra est au dessus de l'écran, faux sinon
    */
    bool camIsAbove;
    /*!
      Champ de la caméra, en radians
    */
    double field;
    /*!
      Échelle à utiliser
    */
    double scaling;
    /*!
      Radians par pixel pour la caméra
    */
    double radPerPix;

    /*!
      Distance originale des deux yeux \see setOriginalPositions
    */
    double originalD;
    /*!
      Angle original du segment formé par les deux yeux par rapport
      à l'horizontal \see setOriginalPositions
    */
    double originalTheta;

};

#endif // HEADPOSITION_H
